#include "threadA.h"
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <map>
#include "ThreadManager.h"
#include <unistd.h>
#include <string>
#include <time.h>

#define random(x) (rand()%x)

using namespace std;


int CThreadA::setID(int id)
{
	m_id = id;
	return 0;
}

int CThreadA::getID()
{
	return m_id;
}


void CThreadA::handleInt(const int& item, const Theron::Address from)
{
	srand((int)time(0));
	printf("CThreadA receive data with int type: %d \n", item);
	int data = random(100);
	sleep(2);
	Send(data, from);
}

void CThreadA::handleString(const std::string & data, const Theron::Address from)
{
	int num = atoi(data.c_str());
	send2ThreadbyID(num, num);
}

int CThreadA::send2ThreadbyID(int data, int ID)
{
	map<int, Theron::Address>::iterator iter;
	//ThreadManager* threadManager = ThreadManager::instance();
	std::map<int, Theron::Address> temp = CDataCenter::instance()->ID_ADDRESS_MAP;
	iter = CDataCenter::instance()->ID_ADDRESS_MAP.find(ID);
	if (iter != CDataCenter::instance()->ID_ADDRESS_MAP.end())
	{
		Send(data, iter->second);
		return 0;
	}

	return -1;
}

void CThreadA::start()
{
	int num = ThreadManager::instance()->m_num++;
	printf("IN CThreadA start,num:%d", num);
}

//it has several params
void CThreadA::onTimer(void *args)
{
	int* pInt = nullptr;
	CThreadA* pThread = nullptr;
	time_t timer;
	struct tm *tblock;
	timer = time(NULL);
	tblock = localtime(&timer);
	printf("Local time is: %s  ", asctime(tblock));

	ArgumentM* p_arg = (ArgumentM*)args;// the ArgumentM has two args;
	ArgumentM::iterator itr = p_arg->find(PARAM_ONE);
	if (itr == p_arg->end())
	{
		return;
	}
	pInt = (int*)itr->second;

	itr = p_arg->find(THREAD_ADDRESS);
	if (itr == p_arg->end()) {
		return;
	}
	pThread = (CThreadA*)itr->second;

	int timeid = *pInt;
	int num = 0;
	switch (timeid) {
	case TIME_ID_ONE:
		pThread->send2ThreadbyID(1, 1);

		num = ThreadManager::instance()->m_num++;
		printf("num:%d\n", num);
		printf("TIME ID ONE\n");
		break;
	case TIME_ID_TWO:
		printf("TIME ID TWO\n");
		//pThread->start();
		break;
	default:
		break;
	}
}

//param is just timeid
//void CThreadA::onTimer(void *args)
//{
//    time_t timer;
//    struct tm *tblock;
//    timer = time(NULL);
//    tblock = localtime(&timer);
//    printf("Local time is: %s  ", asctime(tblock));
//
//    string* arg = (string*)args;
//    string str = *arg;
//
//    int timeid = atoi(str.c_str());
//
//    switch(timeid){
//        case TIME_ID_ONE:
//            printf("TIME ID ONE\n");
//            break;
//        case TIME_ID_TWO:
//            printf("TIME ID TWO\n");
//            break;
//        default:
//            break;
//    }
//}

//void CThreadA::onTimer(void *args)
//{
//    time_t timer;
//    struct tm *tblock;
//    timer = time(NULL);
//    tblock = localtime(&timer);
//    printf("Local time is: %s  ", asctime(tblock));
//
//    printf("onTimer(): ");
//
//    int* arg = (int*)args;
//
//    int timeid = *arg;
//
//    printf("%d\n",timeid);
//    switch(timeid){
//        case TIME_ID_ONE:
//            printf("TIME ID ONE\n");
//            break;
//        case TIME_ID_TWO:
//            printf("TIME ID TWO\n");
//            break;
//        default:
//            break;
//    }
//}

//param is just timeid
//void CThreadA::setTimer(int millisecond, int timeid)
//{
//    printf("Timeid:%d\n",timeid);
//    string id = to_string(timeid);
//    m_timerid_map.insert(pair<int,string>(timeid,id));
//
//    map<int,string>::iterator itr = m_timerid_map.find(timeid); //it must can be found
//
//    Timer* t = new Timer();
//
//    t->start(millisecond,&onTimer, reinterpret_cast<void*>(&(itr->second)));
//
//    m_timer_map.insert(pair<int,Timer*>(timeid,t));
//}

//it has several params
void CThreadA::setTimer(int millisecond, int timeid)
{
	printf("Timeid:%d\n", timeid);

	int_timerid_map.insert(pair<int, int>(timeid, timeid));   //first we must save the timeid in int_timerid_map
															//thought the ArgumentM use timeid's address
	map<int, int>::iterator it = int_timerid_map.find(timeid);//it must can be found

	ArgumentM arg;  //secondly we must save the two param(CThread-address and timeid's address) in ArgumentM
	arg.insert(pair<int, void*>(THREAD_ADDRESS, reinterpret_cast<void*>(this)));
	arg.insert(pair<int, void*>(PARAM_ONE, reinterpret_cast<void*>(&(it->second))));

	m_timeargs_map.insert(pair<int, ArgumentM>(timeid, arg)); //third,we should save the ArgumentM in m_timeargs_map
															//thought the ArgumentM is used in onTimer()
	map<int, ArgumentM>::iterator itr = m_timeargs_map.find(timeid);//it must can be found

	Timer* t = new Timer();

	t->start(millisecond, &onTimer, reinterpret_cast<void*>(&(itr->second)));

	m_timer_map.insert(pair<int, Timer*>(timeid, t));
}

void CThreadA::cancelTimer(int timeid)
{
	map<int, Timer*>::iterator itr = m_timer_map.find(timeid);
	if (itr != m_timer_map.end())
	{
		itr->second->stop();
		m_timer_map.erase(itr);
	}

	map<int, int>::iterator it = int_timerid_map.find(timeid);
	if (it != int_timerid_map.end())
	{
		int_timerid_map.erase(it);
	}

	map<int, ArgumentM>::iterator itr1 = m_timeargs_map.find(timeid);
	if (itr1 != m_timeargs_map.end())
	{
		m_timeargs_map.erase(itr1);
	}
}